package com.ruoyi.common.utils.http;

import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;

/**
 * 
 * http请求公用类
 * @author liumaotong
 * @date 2021-08-03
 */
@Slf4j
public class HttpReqRespUtil {

    /**
     * http get请求
     * 
     * @param url
     * @return
     */
    public static JSONObject sendGet(String url) {
        JSONObject jsonObject = null;
        jsonObject = httpRequest(url, "GET", null, null);
        return jsonObject;
    }

    /**
     * http get请求
     * 
     * @param url
     * @return
     */
    public static JSONObject sendGet(String url, Map<String, Object> headers) {
        JSONObject jsonObject = null;
        jsonObject = httpRequest(url, "GET", null, headers);
        return jsonObject;
    }

    /**
     * http get请求
     * 
     * @param url
     * @return
     */
    public static JSONObject sendGet(String url, String output, Map<String, Object> headers) {
        JSONObject jsonObject = null;
        jsonObject = httpRequest(url, "GET", output, headers);
        return jsonObject;
    }

    /**
     * http post请求
     * 
     * @param url
     * @return
     */
    public static JSONObject sendPost(String url) {
        JSONObject jsonObject = null;
        jsonObject = httpRequest(url, "POST", null, null);
        return jsonObject;
    }

    /**
     * http post请求
     * 
     * @param url
     * @param output
     *            json串
     * @return
     */
    public static JSONObject sendPost(String url, String output) {
        JSONObject jsonObject = null;
        jsonObject = httpRequest(url, "POST", output, null);
        return jsonObject;
    }

    /**
     * http post
     * @Description：方法功能描述
     * @param url
     * @param output
     * @param headers
     * @return: 返回结果描述
     * @return JSONObject: 返回值类型
     * @throws
     */
    public static JSONObject sendPost(String url, String output, Map<String, Object> headers) {
        JSONObject jsonObject = null;
        jsonObject = httpRequest(url, "POST", output, headers);
        return jsonObject;
    }

    /**
     * @Author liumaotong
     * @Description 发送post请求，发送入参为xml格式字符串 CTOS接口专用
     * @Date 2021/8/3
     * @Param [url, output]
     * @return java.lang.String
     **/
    public static String sendPostForXml(String url, String output) {
        String result = httpRequestForXml(url, "POST", output, null);
        return result;
    }

    public static String sendGetForXml(String url) {
        String result = httpRequestForXml(url, "GET", null, null);
        return result;
    }

    /**
     * 发起https请求并获取结果
     * 请求地址
     * @param requestMethod
     *            请求方式（GET、POST） 提交的数据
     * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
     */
    private static JSONObject httpRequest(String request, String requestMethod, String output,
                                          Map<String, Object> headers) {
        JSONObject jsonObject = null;
        StringBuilder buffer = new StringBuilder();
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader reader = null;
        try {
            log.debug("[HTTP]", "http请求request:{},method:{},output{}",
                    new Object[] { request, requestMethod, output });
            // 建立连接
            URL url = new URL(request);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setConnectTimeout(3000);
            connection.setReadTimeout(30000);
            connection.setUseCaches(false);
            connection.setRequestMethod(requestMethod);
            connection.setRequestProperty("Content-Type", "application/json");
            if (headers != null) {
                for (Map.Entry<String, Object> entry : headers.entrySet()) {
                    connection.setRequestProperty(entry.getKey(), entry.getValue().toString());
                }
            }
            if (output != null) {
                OutputStream out = connection.getOutputStream();
                out.write(output.getBytes("UTF-8"));
                out.close();
            }
            // 流处理
            inputStream = connection.getInputStream();
            inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
            reader = new BufferedReader(inputStreamReader);
            String line;
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            // 关闭连接、释放资源
            reader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
            connection.disconnect();
            jsonObject = JSONObject.parseObject(buffer.toString());
            if (null == jsonObject) {
                jsonObject = new JSONObject();
                jsonObject.put("-1", "调用接口异常");
            }
        } catch (Exception e) {
            log.error(e.toString());
            e.printStackTrace();
            jsonObject = new JSONObject();
            jsonObject.put("-1", "调用接口异常");
        }
        return jsonObject;
    }

    /**
     * @Author liumaotong
     * @Description 发送http请求返回String，此方法为CTOS接口调用专用
     * @Date 2021/8/3
     * @Param [request, requestMethod, output, headers]
     * @return java.lang.String
     **/
    private static String httpRequestForXml(String request, String requestMethod, String output,
                                          Map<String, Object> headers) {
        String response = null;
        StringBuilder buffer = new StringBuilder();
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader reader = null;
        try {
            log.debug("[HTTP]", "http请求request:{},method:{},output{}",
                    new Object[] { request, requestMethod, output });
            // 建立连接
            URL url = new URL(request);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setConnectTimeout(30000);
            connection.setReadTimeout(180000);
            connection.setUseCaches(false);
            connection.setRequestMethod(requestMethod);
            connection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
            if (headers != null) {
                for (Map.Entry<String, Object> entry : headers.entrySet()) {
                    connection.setRequestProperty(entry.getKey(), entry.getValue().toString());
                }
            }
            if (output != null) {
                OutputStream out = connection.getOutputStream();
                out.write(output.getBytes("UTF-8"));
                out.close();
            }
            // 流处理
            inputStream = connection.getInputStream();
            inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
            reader = new BufferedReader(inputStreamReader);
            String line;
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            // 关闭连接、释放资源
            reader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
            connection.disconnect();
            response = buffer.toString();
            if (null == response) {
                response = "调用接口异常";
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            e.printStackTrace();
            response = "调用接口异常";
        }
        return response;
    }

}
